﻿using System;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace FileSystemCustomClasses
{
	public interface IFileSystemEngine
	{
		event EventHandler<FileListUpdateArgs> OnUpdate;
		void GetFileList(string argPath);
	}

	public class FileSystemEngine : IFileSystemEngine
	{
		private FileSystemListService _fileSystemListService;
		private SynchronizationContext _uiContext;

		public FileSystemEngine(SynchronizationContext argContext)
		{
			_uiContext = argContext;
		}

		public event EventHandler<FileListUpdateArgs> OnUpdate;

		public void GetFileList(string argPath)
		{
			_fileSystemListService = new FileSystemListService();

			Thread makeList = new Thread(MakeList);
			Thread updateUI = new Thread(UpdateUI);

			makeList.Start(argPath);
			updateUI.Start();
		}

		private void UpdateUI()
		{
			while (true)
			{
				//TakeAll will wait for the List to have items before continuing.
				FileListUpdateArgs localArgs = new FileListUpdateArgs(_fileSystemListService.TakeAll());

				_uiContext.Send(RaiseOnUpdate, localArgs);

				if (_fileSystemListService.IsCompleted)
				{
					//One last grasp to make sure I got all the items
					localArgs = new FileListUpdateArgs(_fileSystemListService.TakeAll());
					Debug.WriteLine("IsComplete: " + localArgs.ItemList.Count);

					_uiContext.Send(RaiseOnUpdate, localArgs);

					break;
				}
			}
		}

		private void RaiseOnUpdate(object argState)
		{
			OnUpdate.Raise(this, argState as FileListUpdateArgs);
		}

		private void MakeList(object argPathObj)
		{
			//Get the path
			//Get a list of IOItems in the path
			DirectoryInfo localDirectory = new DirectoryInfo(argPathObj.ToString());

			FileSystemInfo[] localList = localDirectory.GetFileSystemInfos();

			//TODO: Way to report the count and progress back to the front end
			//localItemCount = localList.Count();

			foreach (FileSystemInfo currentFileSystemInfo in localList)
			{
				FileSystemItem localItem;
				if (currentFileSystemInfo is DirectoryInfo)
				{
					localItem = new DirectoryItem(currentFileSystemInfo);
				}
				else
				{
					localItem = new FileItem(currentFileSystemInfo);
				}

				_fileSystemListService.Add(localItem);
			}

			_fileSystemListService.IsCompleted = true;
		}
	}
}